{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "# Creating a RISC-V Processor Bitstream\n",
    "\n",
    "**The following steps should all be run on your host computer.** \n",
    "\n",
    "In this step we will be creating a FPGA Bitstream with a RISC-V Processor. The following steps can **(and should be)** completed in parallel with [Compiling the RISC-V GCC Toolchain](3-Compiling-RISC-V-GCC-Toolchain.ipynb) since the compilation process will take several hours. \n",
    "\n",
    "After completing [the previous notebook](1-Downloading-And-Configuring.ipynb) we have two repositories on our host machine: RISC-V-On-PYNQ, and riscv-gnu-toolchain. Our RISC-V-On-PYNQ repository clone is located at `/home/xilinx/RISC-V-On-PYNQ`. This repository also cloned the PicoRV32 RISC-V Processor repository, located at `/home/xilinx/RISC-V-On-PYNQ/picorv32`.\n",
    "\n",
    "This notebook has two parts:\n",
    "\n",
    "**[Packaging RISC-V Source as Vivado IP](2-Creating-A-Bitstream.ipynb#Packaging-RISC-V-Source-as-Vivado-IP)**. In this part we will package the PicoRV32 source as a Xilinx IP. Later we will use it in a Vivado Block Design design which will generate `.tcl` script used in PYNQ\n",
    "\n",
    "**[Creating a RISC-V Bitstream for the PYNQ-Z1](2-Creating-A-Bitstream.ipynb#Creating-a-RISC-V-Bitstream-for-the-PYNQ-Z1)**. This part uses the PicoRV32 RISC-V IP from above in a Vivado Block Design, exports it as a `.tcl` file, and compiles the design.\n",
    "\n",
    "<div class=\"alert alert-block alert-info\">\n",
    "**Note:** If you are using another RISC-V project, you may need to handle different interface standards, or multiple memory interfaces. Refer to section entitled **[RISC-V Project Variations](2-Creating-A-Bitstream.ipynb#RISC-V-Project-Variations)**.\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Skipping Steps in this Notebook\n",
    "\n",
    "To skip the first step, **[Packaging RISC-V Source as Vivado IP](2-Creating-A-Bitstream.ipynb#Packaging-RISC-V-Source-as-Vivado-IP)**, copy the `picorv32_tutorial` folder from `<Path-To-RISC-V-On-PYNQ>/ip/gold/` to ` <Path-To-RISC-V-On-PYNQ>/ip/`. \n",
    "\n",
    "If your repository is located in your home directory this can be accomplished with the following command:\n",
    "\n",
    "```bash\n",
    "    cp -r ~/RISC-V-On-PYNQ/ip/gold/picorv32_tutorial/ ~/RISC-V-On-PYNQ/ip/\n",
    "```\n",
    "\n",
    "To skip the second step, **[Creating a RISC-V Bitstream for the PYNQ-Z1](2-Creating-A-Bitstream.ipynb#Creating-a-RISC-V-Bitstream-for-the-PYNQ-Z1)**, copy `tutorial.tcl` and `tutorial.bit` from ` <Path-To-RISC-V-On-PYNQ>/riscvonpynq/picorv32/tut/gold/` to ` <Path-To-RISC-V-On-PYNQ>/riscvonpynq/picorv32/tut/`. For example, on our Linux host machine we would run the following command in a BASH shell to skip the step \n",
    "\n",
    "If your repository is located in your home directory, this can be accomplished with the following commands:\n",
    "\n",
    "```bash\n",
    "    cp ~/RISC-V-On-PYNQ/riscvonpynq/picorv32/tut/gold/tutorial.tcl ~/RISC-V-On-PYNQ/riscvonpynq/picorv32/tut/\n",
    "\n",
    "    cp ~/RISC-V-On-PYNQ/riscvonpynq/picorv32/tut/gold/tutorial.bit ~/RISC-V-On-PYNQ/riscvonpynq/picorv32/tut/\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Packaging RISC-V Source as Vivado IP\n",
    "\n",
    "In this step we will package the the PicoRV32 RISC-V Processor source files as a Vivado IP for use in Block Diagram Editor. The Block Diagram editor will be used to generate a `.tcl` file that will be used when loading an PYNQ Overlay. \n",
    "\n",
    "These steps are a summary of the information available in the [Vivado Creating and Packaging Custom IP Tutorial](https://www.xilinx.com/support/documentation/sw_manuals/xilinx2017_4/ug1119-vivado-creating-packaging-ip-tutorial.pdf).\n",
    "\n",
    "To begin, launch Vivado 2017.4. This can be done by running the following command in a terminal: \n",
    "\n",
    "    vivado\n",
    "\n",
    "On a Windows host, you can launch vivado from the Start Menu. You will be presented with the following screen:\n",
    "\n",
    "<img src=\"pictures/vivado_welcome.png\" alt=\"The Vivado 2017.4 Welcome Screen\" style=\"width: 768px;\"/>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Creating a Project\n",
    "\n",
    "To begin, click the **Create Project** button under the green **Quick Start** heading on the welcome screen. This will open the window in the next image. \n",
    "\n",
    "<img src=\"pictures/vivado_new_project.png\" alt=\"Creating a New Project\" style=\"width: 512px;\"/>\n",
    "\n",
    "For this tutorial we will create a project named picorv32_prj inside of the ` <Path-To-RISC-V-On-PYNQ>/ip/` folder of the RISC-V-On-PYNQ repository that was cloned in [Downloading Dependencies](1-Downloading-And-Configuring.ipynb).\n",
    "\n",
    "Click **Next** when done. Select **RTL Project** in the subsequent window and click **Next** again to continue to the next step."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Adding Source Files\n",
    "\n",
    "The next step is to add source files to the project. In the **Add Sources** window shown below, click the **+** symbol and navigate to the location of the PicoRV32 RISC-V repository inside the RISC-V-On-PYNQ Repository. On our host machine this repository is located at `/home/xilinx/RISC-V-On-PYNQ/picorv32/`\n",
    "\n",
    "<img src=\"pictures/vivado_add_sources.png\" alt=\"The Add Sources window. Click the + symbol to proceed to the next window.\" style=\"width: 512px;\"/>\n",
    "\n",
    "Add the `picorv32.v` source file from the PicoRV32 RISC-V Processor repository to your project as shown in the second window. \n",
    "\n",
    "<img src=\"pictures/vivado_add_source_picorv32.png\" alt=\"Navigate to the picorv32 repository and add the picorv32.v top level file.\" style=\"width: 512px;\"/>\n",
    "\n",
    "\n",
    "<div class=\"alert alert-block alert-info\">\n",
    "**Note:** If you are following this guide but using a different processor you will need to add the corresponding top level file and any additional sub-files using the same process. \n",
    "</div>\n",
    "\n",
    "<div class=\"alert alert-block alert-info\">\n",
    "**Note:** The processor you choose should have LMB, BRAM, AXI4, AXI4Lite, AHB, Avalon, or Wishbone interfaces for the best integration with Vivado Block Diagram Editor.\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Configuring the Project\n",
    "\n",
    "Once you have added all the source files to your project, the final step is to select the chip for your project. Click **Next** until you arrive at the **Part Selection** window shown below. In the search box type **xc7z020clg400-1** and select the Zynq chip in the window. This is the chip on the PYNQ-Z1 board. Click **Next** when done.\n",
    "\n",
    "<img src=\"pictures/vivado_part_selection.png\" alt=\"Select the xc7z020clg400-1 from the part menu.\" style=\"width: 512px;\"/>\n",
    "\n",
    "If you have created the project successfully, you should see the following **Project Manager** window:\n",
    "\n",
    "<img src=\"pictures/vivado_project_done.png\" alt=\"Successful Vivado Project Creation Page\" style=\"width: 768px;\"/>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Add a Custom Interface IP to the Vivado Project\n",
    "\n",
    "We provide an IP Interface that will encapsulate the [PCPI interface](https://github.com/cliffordwolf/picorv32#pico-co-processor-interface-pcpi) provided by the picorv32. \n",
    "\n",
    "To use this interface you must add a Custom IP Repository by selecting **Tools** > **Settings...** from the Vivado GUI. In the window that is presented, expand the **IP** menu from the sidebar and then click on **repositories**\n",
    "\n",
    "This will bring up the following window: \n",
    "\n",
    "<img src=\"pictures/custom_repository.png\" alt=\"Add a custom repository from the Tools > Settings... menu\" style=\"width: 512px;\"/>\n",
    "\n",
    "Click the **+** symbol to add a repository. Navigate to the `<Path-To-RISC-V-On-PYNQ>/ip/` folder of the PYNQ-RISC-V repository and click **Add**. It should find the PCPI interface located in the `pcpi_v1_0` folder. \n",
    "\n",
    "Check that your work matches the window shown above before continuing.\n",
    "\n",
    "<div class=\"alert alert-block alert-info\">\n",
    "**Note:** Other projects provide a variety of interfaces for extensions, debuggers, and peripherals. You can create new custom interfaces by following the guide in **[Vivado Creating and Packaging Custom IP Tutorial](https://www.xilinx.com/support/documentation/sw_manuals/xilinx2017_1/ug1119-vivado-creating-packaging-ip-tutorial.pdf)**\n",
    "</div>\n",
    "\n",
    "After adding the interface, return to the **Project Manager** window"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Packaging the picorv32 Vivado Project as an IP\n",
    "\n",
    "Back in the Vivado **Project Manger** window, click on **Tools** > **Create and Package New IP...**. This will bring up the splash window shown below.  \n",
    "\n",
    "<img src=\"pictures/vivado_create_new_ip_splash.png\" alt=\"Splash window for Create and Package new IP\" style=\"width: 512px;\"/>\n",
    "\n",
    "In the **Next** window, make sure that the **Package your current project** option is selected. Click **Next** to continue. \n",
    "\n",
    "<img src=\"pictures/vivado_packaging_options.png\" alt=\"Specify the source of your new IP.\" style=\"width: 512px;\"/>\n",
    "\n",
    "In the final window specify the destination for your packaged IP. You should specify the path ` <Path-To-RISC-V-On-PYNQ>/ip/picorv32_tut`.  \n",
    "\n",
    "<img src=\"pictures/vivado_create_new_ip_location.png\" alt=\"Specify the destination folder of your IP\" style=\"width: 512px;\"/>\n",
    "\n",
    "Before continuing, make sure that your window matches the one shown above. Click **Next**, and confirm that you want to create a folder for your New IP."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Configuring Your New IP\n",
    "\n",
    "#### Identification Window\n",
    "\n",
    "Click **Next** until you arrive at the screen shown below: \n",
    "\n",
    "<img src=\"pictures/vivado_create_new_ip_identification.png\" alt=\"Configure the identification parameters of your new IP\" style=\"width: 768px;\"/>\n",
    "\n",
    "Specify the name of your RISC-V processor on this screen. You can match the settings shown above."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Customization Parameters Window: \n",
    "\n",
    "In the **Customization Parameters** window we will specifying the PicoRV32 configuration parameters. These parameters will appear in the Vivado IP Integrator Configuration GUI when instantiating a processor. \n",
    "\n",
    "You should match the settings in window shown below.\n",
    "\n",
    "<img src=\"pictures/vivado_create_new_ip_customization.png\" alt=\"Specify the types of all the customization parameters for the picorv32\" style=\"width: 768px;\"/>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Ports and Interfaces Window:\n",
    "\n",
    "When finished, click on **Ports and Interfaces** and verify that the *mem_axi* and *ip_pcpi* interfaces are present. Your screen should match the screen shown below.\n",
    "\n",
    "If the *ip_pcpi* port is not present verify that the custom IP repository was correctly added in the **[Add Custom Interface IP to the Vivado Project](2-Creating-A-Bitstream.ipynb#Add-a-Custom-Interface-IP-to-the-Vivado-Project)** step above\n",
    "\n",
    "<img src=\"pictures/vivado_create_new_ip_ports.png\" alt=\"Verify that Vivado has correctly recognized the PCPI and AXI ports in the picorv32 RISC-V Processor\" style=\"width: 768px;\"/>\n",
    "\n",
    "Right click on mem_axi and open the edit interface window and change the interface definition to aximm_rtl.\n",
    "\n",
    "<img src=\"pictures/Edit_interface.PNG\" alt=\"Change the interface description to aximm_rtl\" style=\"width: 768px;\"/>\n",
    "\n",
    "Click on the port mapping window and map all the mem_axi ports under the IP's physical ports with the corresponding Interface's Logical Ports.\n",
    "\n",
    "<img src=\"pictures/Port_Mapping.PNG\" alt=\"Map the logical and physical ports\" style=\"width: 768px;\"/>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Addressing and Memory\n",
    "\n",
    "Next, click on **Addressing and Memory** to bring up the following window. Confirm that your settings match the values shown below: \n",
    "\n",
    "<img src=\"pictures/vivado_create_address_map.png\" alt=\"Verify that Vivado has correctly set the address map parameters in the PicoRV32 RISC-V Processor\" style=\"width: 768px;\"/>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Review and Package\n",
    "\n",
    "Finally, proceed to **Review and Package** and click **Package IP**\n",
    "\n",
    "Congratulations! You have packaged a Vivado IP. You can verify that your processor IP was packaged correctly by checking for the `picorv32_tut` folder in `RISC-V-On-PYNQ/ip/`. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Creating a RISC-V Bitstream for the PYNQ-Z1\n",
    "\n",
    "The following steps describe how to build and implement a RISC-V bitstream containing a PicoRV32 RISC-V processor for the PYNQ-Z1. This will result in a `tutorial.tcl` file that is used to compile an FPGA bitstream."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To simplify the creation of a base project we have provided a `tutorial.tcl` file in the `RISC-V-On-PYNQ/riscvonpynq/picorv32/tutorial` folder of the PYNQ-RISC-V repository. This `.tcl` file: \n",
    "\n",
    "1. Creates a Vivado Project with the appropriate design contraints file\n",
    "2. Creates a new block diagram in IP Integrator\n",
    "3. Adds PYNQ-Z1 IO ports to the block diagram\n",
    "4. Instantiates a ZYNQ ARM PS with the correct operating settings.\n",
    "5. Instantiates all block design IP, with the correct settings.\n",
    "\n",
    "The `tutorial.tcl` file is used by `build.tcl`. `build.tcl` does the following:\n",
    "\n",
    "1. Adds the custom IP directory `RISC-V-On-PYNQ/ip` to the search path.\n",
    "2. Compiles the design into a `.bit` file\n",
    "\n",
    "`build.tcl` can also be used to perform frequency sweeps. See the documentation in the file for more information.\n",
    "\n",
    "In these steps you will be responsible for creating your own overlay using the `tutorial.tcl` file. These steps demonstrate a BRAM-Memory Processor Overlay, where the PicoRV32 is connected only to BRAM memory. \n",
    "\n",
    "Other examples in our repository demonstrate a **Mixed Processor Overlay**, where the RISC-V Processor has access to BRAM and DDR Memory."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### BRAM Processor Overlay\n",
    "\n",
    "To begin, you will need to build the starter block design. You can do this inside the `<Path-To-RISC-V-On-PYNQ>` using the makefile provided. This can be done on from a terminal on your host by running the following command:\n",
    "\n",
    "    make -C <Path-To-RISC-V-On-PYNQ>/riscvonpynq/picorv32/tut/ synth\n",
    "\n",
    "This will generate and synthesize the block design. When it has finished, open the project by running the following command: \n",
    "   \n",
    "    vivado  tutorial/tutorial.xpr\n",
    "\n",
    "You will be presented with the **Project Manager Window**:\n",
    "\n",
    "<img src=\"pictures/vivado_project_manager_tutorial.png\" alt=\"Output of the tutorial.tcl scipt\" style=\"width: 768px;\"/>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Adding your IP to the Block Diagram\n",
    "\n",
    "Now we will add a RISC-V processor to our block diagram. Under **Design Sources** open the tutorial.bd Block Diagram file: \n",
    "\n",
    "<img src=\"pictures/vivado_project_manager_bd.png\" alt=\"Open the tutorial.bd file\" style=\"width: 768px;\"/>\n",
    "\n",
    "This will open the block diagram. You should see the following window: \n",
    "\n",
    "<img src=\"pictures/vivado_block_diagram_initial.png\" alt=\"An Unmodified Tutorial Block Diagram\" style=\"width: 768px;\"/>\n",
    "\n",
    "This block design has everything needed to run a RISC-V Processor: Memory, Resets, Interrupt Request Pins (IRQ), and a  Hierarchy. However, it does not include a RISC-V processor. To add the RISC-V Processor we created in the previous step, open the tutorialProcessor Hierarchy. This will open the following window:  \n",
    "\n",
    "<img src=\"pictures/vivado_block_diagram_hier_bram.png\" alt=\"The bramProcessor IP Hierarchy\" style=\"width: 768px;\"/>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Adding the RISC-V processor. \n",
    "\n",
    "We must add the RISC-V Processor.  Click on the **+** symbol at the top of the Block Diagram Editor and search for your PicoRV32 packaged IP. If you matched the settings in **[Packaging the picorv32 Vivado Project as an IP](2-Creating-A-Bitstream.ipynb#Packaging-the-picorv32-Vivado-Project-as-an-IP)** you will search for the name 'PicoRV32 Processor with AXI Interface (Tutorial Version)'. Adding the IP will result in the following block diagram:\n",
    "\n",
    "<img src=\"pictures/vivado_block_diagram_hier_new_picorv32.png\" alt=\"Result of adding the PicoRV32 Processor IP Block\" style=\"width: 768px;\"/>\n",
    "\n",
    "\n",
    "Connect the wiring as shown in the Figure Below: \n",
    "\n",
    "<img src=\"pictures/vivado_block_diagram_hier_wired.png\" alt=\"Result of wiring the PicoRV32 Processor IP Block\" style=\"width: 768px;\"/>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Assigning the Block Diagram Address Map\n",
    "\n",
    "The final step in the process is to assign address ranges to each of the AXI ports. Click on the **Address Editor** tab at the top of the Block Diagram Editor in Vivado. For each unmapped slave, right click on the slave and select **Assign Address**. Follow the directions below:\n",
    "\n",
    "- For **mem_axi/riscvBramController** assign the address 0x0000_0000 and size 64K.\n",
    "\n",
    "The first two addresses are the Main and IO memory mappings for the RISC-V processor. As configured, the picorv32 processor will read instructions starting at address 0x0000_0000. \n",
    "\n",
    "After these assignments your settings should match the settings shown below.\n",
    "\n",
    "<img src=\"pictures/vivado_block_diagram_address_map.png\" alt=\"Final Address Map\" style=\"width: 768px;\"/>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Generating a Bitstream\n",
    "\n",
    "If everything is connected correctly then running **Tools** > **Validate Design** only show a warning about unconnected PCPI ports. If this succeeds, then the design is ready to compile. Click **Generate Bitstream** to generate your bitstream.\n",
    "\n",
    "After your bitstream has been generated, proceed to the next step."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exporting your Design to a .tcl file.\n",
    "\n",
    "The last step in the process is to export your design to a .tcl file. To do this, we will be updating the `tutorial.tcl` file in `<Path-To-RISC-V-On-PYNQ>/riscvonpynq/picorv32/tut/`.\n",
    "\n",
    "Open your block design and click **File** > **Export** > **Export Block Design...**. You should export your design to the same location and overwrite the `tutorial.tcl` file you ran in the first step.\n",
    "\n",
    "<div class=\"alert alert-block alert-info\">\n",
    "**Note:** If you do not see the **Export Block Design...*** make sure you have opened your block design.\n",
    "</div>\n",
    "\n",
    "<div class=\"alert alert-block alert-danger\">\n",
    "**Note:** This will overwrite `tutorial.tcl`. You can always return to the original `tutorial.tcl` file using the command: `git checkout tutorial.tcl`.\n",
    "</div>\n",
    "\n",
    "You should match the window below by moving the output up one level in the directory tree (i.e. removing one instance of `tutorial`).\n",
    "\n",
    "<img src=\"pictures/vivado_block_diagram_export.png\" alt=\"Setting the Block Diagram Export Path\" style=\"width: 512px;\"/>\n",
    "\n",
    "**DON'T FORGET TO UNCHECK THE \"AUTOMATICALLY CREATE TOP LEVEL DESIGN\" BOX**\n",
    "\n",
    "When done, save the files. \n",
    "\n",
    "To generate the files run the following command: \n",
    "\n",
    "    make -C <Path-To-RISC-V-On-PYNQ>/riscvonpynq/picorv32/tut/ single\n",
    "    \n",
    "To perform a frequency sweep, you can run the following command: \n",
    "\n",
    "    make -C <Path-To-RISC-V-On-PYNQ>/riscvonpynq/picorv32/tut/ sweep\n",
    "\n",
    "**Congratulations you have created a RISC-V bitstream**"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
